package top.hmtools.captcha.configuration;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.beans.BeansException;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import top.hmtools.base.StringTools;

@Configuration
@ServletComponentScan
@ComponentScan(basePackages={"top.hmtools.captcha"})
@ConditionalOnProperty(prefix=CaptchaAutoConfiguration.config_prefix,value="enabled",havingValue="true",matchIfMissing=true)
public class CaptchaAutoConfiguration implements ApplicationContextAware{
	
	private ApplicationContext applicationContext;
	
	public static final String config_prefix = "top.hmtools.captcha";
	
	/**
	 * 验证码内容存入session的key
	 */
	public static final String SESSION_CAPTCHA_KEY = "session_captcha";

	/**
	 * 验证码内容存入session的时间戳 key
	 */
	public static final String SESSION_CAPTCHA_TIMESTAMP_KEY = "session_captcha_timestamp";

	/**
	 * 获取工程名称
	 * @return
	 */
	public String getProjectName(){
		return this.getProperty("project.name", "请在配置文件中设置“project.name”的值");
	}

	/**
	 * 获取工程版本
	 * @return
	 */
	public String getProjectVersion(){
		return this.getProperty("project.version", "请在配置文件中设置“project.version”的值");
	}
	
	/**
	 * 获取工程字符编码
	 * @return
	 */
	public String getProjectEncoding(){
		return this.getProperty("project.encoding", "utf-8");
	}

	/**
	 * 根据配置键名获取配置值，如果没有，则使用缺省值。
	 * <br>可获取system环境信息、spring boot配置信息
	 * @param key
	 * @param defaultValue
	 * @return
	 */
	private String getProperty(String key,String defaultValue){
		String result = this.applicationContext.getEnvironment().getProperty(key, defaultValue).trim();
		if(StringTools.isBlank(result)){
			result = defaultValue;
		}
		return result;
	}

	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		this.applicationContext=applicationContext;
	}
	
	/**
	 * 获取线程安全的当前请求的HttpServletRequest对象实例
	 * @return
	 */
	public HttpServletRequest getRequest(){
		return ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
	}
	
	/**
	 * 获取线程安全HttpServletResponse对象实例
	 * @return
	 */
	public HttpServletResponse getResponse(){
		return ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getResponse();
	}
	
	/**
	 * 获取当前请求的session对象实例
	 * @return
	 */
	public HttpSession getSession(){
		return this.getRequest().getSession();
	}

	/**
	 * 获取验证码图片的宽
	 * @return
	 */
	public int getWidth() {
		int result = 120;
		String tmp = this.getProperty(config_prefix+".img.width", String.valueOf(result)).trim();
		try {
			result = Integer.parseInt(tmp);
		} catch (Exception e) {
		}
		return result;
	}

	/**
	 *  获取验证码图片的高
	 * @return
	 */
	public int getHeight() {
		int result = 36;
		String tmp = this.getProperty(config_prefix+".img.height", String.valueOf(result)).trim();
		try {
			result = Integer.parseInt(tmp);
		} catch (Exception e) {
		}
		return result;
	}

	/**
	 * 获取验证码图片的字符数
	 * @return
	 */
	public int getCodeLength() {
		int result = 6;
		String tmp = this.getProperty(config_prefix+".img.code-length", String.valueOf(result)).trim();
		try {
			result = Integer.parseInt(tmp);
		} catch (Exception e) {
		}
		return result;
	}
	
	/**
	 * 获取验证码过期时间，单位：毫秒
	 * @return
	 */
	public long getTimeout(){
		int result = 1*60*1000;
		String tmp = this.getProperty(config_prefix+".timeout", String.valueOf(result)).trim();
		try {
			result = Integer.parseInt(tmp);
		} catch (Exception e) {
		}
		return result;
	}
	
	/**
	 * 获取是否启用过滤器验证http请求指定的URL集合时，请求参数中是否含有验证码且内容是否正确
	 * @return
	 */
	public boolean getIsEnableVerify(){
		return this.applicationContext.getEnvironment().getProperty(config_prefix+".verify.enabled", Boolean.class,false);
	}

	/**
	 * http请求中，携带验证码值得参数名称
	 * @return
	 */
	public String getVerifyParamName() {
		return this.getProperty(config_prefix+".verify.param-name","captcha");
	}
	
	/**
	 * 如果前端请求没有使用cookie传送session id，则只能通过uuid来识别请求是否来自同一终端
	 * @return
	 */
	public String getUuidParamName(){
		return this.getProperty(config_prefix+".uuid.param-name","uuid");
	}

}
